<template>
    <div id="warehouse-list-container" v-loading="loadingStripPlot" element-loading-text="加载数据中..." @contextmenu="disableRightClick">
        <VueUiStripPlot :config="StripPlotConfig" :dataset="dataset" @selectDatapoint="selectDatapoint" />
    </div>

    <!-- 装饰性鼠标光标配置 -->
    <VueUiCursor v-if="showCursor" :config="cursorConfig"></VueUiCursor>

    <!-- 初始化仓库布局 对话框 -->
    <el-dialog v-model="initWarehouseVisible" :show-close="false" fullscreen>
        <template #header="{ close, titleId, titleClass }">
            <div class="my-header">
                <h4 :id="titleId" :class="titleClass">初始化A仓库布局 -- ESC关闭</h4>
                <el-button type="danger" @click="close">
                    <el-icon class="el-icon--left"><CircleCloseFilled /></el-icon>
                    关闭
                </el-button>
            </div>
        </template>
        <div class="flex flex-wrap items-center justify-center">
            <!-- 配置表单 -->
            <el-form class="w-full text-center" :model="initWarehouseForm" :rules="rules" :inline="true">
                <el-form-item label="横坐标">
                    <el-input-number v-model="initWarehouseForm.abscissa" :min="1" :max="26" @change="handleAbscissaChange" />
                </el-form-item>
                <el-form-item label="纵坐标">
                    <el-input-number v-model="initWarehouseForm.ordinate" :min="1" :max="20" @change="handleOrdinateChange" />
                </el-form-item>
                <el-form-item>
                    <el-button plain @click="initWarehouseEvent">确认生成</el-button>
                </el-form-item>
            </el-form>
            <!-- 仓库信息表格 -->
            <table class="w-full">
                <tr v-for="(ord, i) in ordinate" :key="i">
                    <th v-for="(abs, j) in abscissa" :key="j">{{ abs + '-' + ord }}</th>
                </tr>
            </table>
        </div>
    </el-dialog>

    <!-- 修改产品仓库信息 对话框 -->
    <el-dialog v-model="updateProductWarehouseVisible" draggable :show-close="false" width="800">
        <template #header="{ close }">
            <div class="my-header">
                <el-radio-group v-model="updateMode">
                    <el-radio value="update" size="large">修改当前货架</el-radio>
                    <el-radio value="stack" size="large">堆码当前货架</el-radio>
                </el-radio-group>
                <el-button type="danger" plain @click="deleteProductWarehouseSubmitEvent">清空当前货架</el-button>
                <div class="flex items-center">
                    <el-tooltip
                        effect="dark"
                        content="⭐修改模式变更当前货架内容。⭐堆码模式会检测当前货架是否包含即将录入的产品，如果有则直接添加入已有数量中，如果没有则创建新的内容。"
                        placement="bottom"
                    >
                        <el-icon :size="25"><BookQuestionMark20Regular /></el-icon>
                    </el-tooltip>
                </div>
                <el-button class="ml-auto" type="danger" @click="close">
                    <el-icon class="el-icon--left"><CircleCloseFilled /></el-icon>
                    关闭
                </el-button>
            </div>
        </template>
        <div>
            <el-form ref="updateProductWarehouseFormRef" :model="updateProductWarehouseForm" :rules="rules">
                <el-form-item label="产品名称:" required prop="name">
                    <el-autocomplete
                        v-model="updateProductWarehouseForm.name"
                        :fetch-suggestions="queryProductSearch"
                        clearable
                        @select="handleSelect"
                    />
                </el-form-item>
                <el-form-item label="产品数量:" required prop="number">
                    <el-input-number v-model="updateProductWarehouseForm.number" :min="1" :max="1000000" />
                </el-form-item>
                <el-form-item label="仓库位置:" required prop="ordinate">
                    <el-input disabled v-model="updateProductWarehouseForm.ordinate" />
                </el-form-item>
                <el-form-item label="仓库区域:" required prop="abscissa">
                    <el-input disabled v-model="updateProductWarehouseForm.abscissa" />
                </el-form-item>
                <el-form-item>
                    <el-button type="primary" @click="updateProductWarehouseSubmitEvent(updateProductWarehouseFormRef)">提交货架</el-button>
                </el-form-item>
            </el-form>
        </div>
    </el-dialog>
</template>

<script setup lang="ts">
import { FormInstance, FormRules } from 'element-plus';
import { getWarehouseList, initWarehouseList, updateWarehouseInfo } from '@/api/warehouse';
import { getAllProductList } from '@/api/product';
import { CircleCloseFilled } from '@element-plus/icons-vue';
import { BookQuestionMark20Regular } from '@vicons/fluent';
import { VueUiCursor, VueUiStripPlot, VueUiStripPlotConfig } from 'vue-data-ui';
// 装饰性鼠标光标配置
import { cursorConfig } from './config/cursorConfig';
// 引入样式
import 'vue-data-ui/style.css';
import { useSystemStore } from '@/store/modules/system';

onMounted(async () => {
    await getAllWarehouseListEvent();
    await getAllProductListEvent();
});

/* ***********************************通用属性*********************************** */
// 默认仓库名称
const warehouseName = ref('A');
// 加载动画
const loadingStripPlot = ref(true);
// 所有产品数据
const productList = reactive<AjaxResponse['productList']>([]);
// 显示装饰性鼠标光标
const showCursor = computed(() => {
    // 仓库数据为空，则不显示
    if (dataset.length == 0) {
        return false;
    }
    // dialog启动时，则不显示
    if (updateProductWarehouseVisible.value) {
        return false;
    }
    if (initWarehouseVisible.value) {
        return false;
    }

    return true;
});

// 获取所有产品列表
const getAllProductListEvent = async () => {
    // 清空数据
    productList.length = 0;
    // 获取所有产品列表
    getAllProductList().then((res) => {
        res.data.forEach((item) => {
            item.products.forEach((product) => {
                product.value = product.productName;
                productList.push(product);
            });
        });
    });
};
// 获取所有仓库列表
const getAllWarehouseListEvent = async () => {
    // 清空数据
    dataset.length = 0;
    loadingStripPlot.value = true;
    // 加载默认产品仓库列表
    getWarehouseList(warehouseName.value).then((res) => {
        // 仓库没有初始化
        if (res.code == 201) {
            ElMessageBox.confirm(res.message, '提示', {
                confirmButtonText: '确定',
                cancelButtonText: '取消',
                type: 'warning',
            })
                .then(() => {
                    // 确定初始化
                    initWarehouseVisible.value = true;
                })
                .catch(() => {
                    ElNotification({
                        title: '仓库系统提示',
                        type: 'warning',
                        message: '未初始化仓库，无法使用，请先初始化仓库',
                    });
                });
        } else {
            // 处理数据
            for (let index = 0; index < res.data.length; index++) {
                const warehouse = res.data[index];
                // 检查数据中是否含有name 字段
                const i = dataset.findIndex((item) => item.name === warehouse.abscissa);
                // 不含有name字段，说明某列未生成
                if (i == -1) {
                    // 判断数据中是否含有存放信息
                    if (warehouse.info && warehouse.info.length > 0) {
                        // 存在存放信息
                        for (let index = 0; index < warehouse.info.length; index++) {
                            const info = warehouse.info[index];
                            dataset.push({
                                name: warehouse.abscissa,
                                plots: [
                                    {
                                        _id: info._id,
                                        abscissa: warehouse.abscissa,
                                        ordinate: warehouse.ordinate,
                                        productId: info.productId,
                                        name: '存放产品：' + info.productName + ' - 存放数量：' + info.quantity,
                                        value: warehouse.ordinate - 0.5 + index / 10,
                                    },
                                ],
                            });
                        }
                    } else {
                        // 不存在存放信息
                        dataset.push({
                            name: warehouse.abscissa,
                            plots: [
                                {
                                    _id: 'null',
                                    abscissa: warehouse.abscissa,
                                    ordinate: warehouse.ordinate,
                                    productId: 'null',
                                    name: '空货架',
                                    value: warehouse.ordinate - 0.5,
                                },
                            ],
                        });
                    }
                } else {
                    // 判断数据中是否含有存放信息
                    if (warehouse.info && warehouse.info.length > 0) {
                        // 含有name字段，说明列生成，但不为空
                        for (let index = 0; index < warehouse.info.length; index++) {
                            const info = warehouse.info[index];
                            dataset[i].plots.push({
                                _id: info._id,
                                abscissa: warehouse.abscissa,
                                ordinate: warehouse.ordinate,
                                productId: info.productId,
                                name: '存放产品：' + info.productName + ' - 存放数量：' + info.quantity,
                                value: warehouse.ordinate - 0.5 + index / 10,
                            });
                        }
                    } else {
                        // 含有name字段，说明列生成，但是为空
                        dataset[i].plots.push({
                            _id: 'null',
                            abscissa: warehouse.abscissa,
                            ordinate: warehouse.ordinate,
                            productId: 'null',
                            name: '空货架',
                            value: warehouse.ordinate - 0.5,
                        });
                    }
                }
            }

            loadingStripPlot.value = false;
        }
    });
};
// 禁用右键
const disableRightClick = (event) => {
    event.preventDefault(); // 阻止默认右键菜单的显示
};

/* ***********************************StripPlot属性/方法*********************************** */
// 配置
const StripPlotConfig = ref<VueUiStripPlotConfig>({
    // 当图表放置在可调整大小的容器内或容器具有固定尺寸时，请将此属性设置为 true。父容器未设置高度时切勿使用，这将导致图表的高度无限增长
    responsive: true,
    theme: '',
    // string[]
    customPalette: [],
    useCssAnimation: true,
    // 配置工具栏
    userOptions: {
        show: true,
        position: 'right',
        // 工具栏按钮配置
        buttons: {
            tooltip: false,
            pdf: false,
            csv: false,
            img: false,
            table: true,
            labels: false,
            fullscreen: true,
            sort: false,
            stack: false,
            animation: false,
            annotator: true,
        },
        buttonTitles: {
            open: '打开工具栏',
            close: '关闭工具栏',
            tooltip: '切换提示',
            pdf: '下载 PDF',
            csv: '下载 CSV',
            img: '下载 PNG',
            table: '切换 表格',
            labels: '切换 标签',
            fullscreen: '全屏',
            // @ts-ignore
            annotator: '注释',
        },
    },
    // 样式
    style: {
        fontFamily: 'inherit',
        chart: {
            backgroundColor: '#FFFFFFff',
            color: '#1A1A1Aff',
            height: 600,
            stripWidth: 120,
            padding: {
                top: 24,
                right: 24,
                bottom: 64,
                left: 64,
            },
            grid: {
                show: true,
                stroke: '#CCCCCCff',
                // 线条宽度
                strokeWidth: 1,
                // 刻度间隔
                scaleSteps: 10,
                horizontalGrid: {
                    show: true,
                    stroke: '#CCCCCCff',
                    strokeWidth: 0.5,
                    strokeDasharray: 4,
                },
                verticalGrid: {
                    show: true,
                    stroke: '#CCCCCCff',
                    strokeWidth: 0.5,
                    strokeDasharray: 4,
                },
            },
            plots: {
                opacity: 0.5,
                radius: 10,
                stroke: '#FFFFFFff',
                strokeWidth: 1,
                shape: 'circle',
                gradient: {
                    show: true,
                    intensity: 40,
                },
            },
            labels: {
                prefix: '货位号：',
                suffix: '',
                formatter: null,
                bestPlotLabel: {
                    // 最顶端的labels是否显示
                    show: false,
                    showValue: true,
                    fontSize: 14,
                    color: '#1A1A1Aff',
                    rounding: 0,
                    offsetY: 0,
                },
                axis: {
                    xLabel: 'X →',
                    xLabelOffsetY: 0,
                    yLabel: 'Y →',
                    yLabelOffsetX: 0,
                    fontSize: 20,
                    color: '#1A1A1Aff',
                },
                xAxisLabels: {
                    show: true,
                    color: '#1A1A1Aff',
                    fontSize: 14,
                    offsetY: 0,
                },
                // 纵坐标标签
                yAxisLabels: {
                    // 纵坐标标签是否显示
                    show: false,
                    color: '#1A1A1Aff',
                    fontSize: 14,
                    rounding: 0,
                    offsetX: 0,
                },
            },
            title: {
                text: '仓库A',
                color: '#1A1A1Aff',
                fontSize: 20,
                bold: true,
                textAlign: 'center',
                paddingLeft: 0,
                paddingRight: 0,
            },
        },
    },
    table: {
        show: false,
        responsiveBreakpoint: 300,
        columnNames: {
            series: '品名',
            value: '位置',
        },
        th: {
            backgroundColor: '#FFFFFFff',
            color: '#1A1A1Aff',
            outline: 'none',
        },
        td: {
            backgroundColor: '#FFFFFFff',
            color: '#1A1A1Aff',
            outline: 'none',
            roundingValue: 0,
        },
    },
});
// 数据源类型
type Dataset = {
    name: string;
    plots: {
        _id: string;
        abscissa: string;
        ordinate: number;
        productId: string;
        name: string;
        value: number;
    }[];
}[];
// 数据源
const dataset = reactive<Dataset>([]);
// 修改数据的模式
const updateMode = ref<'update' | 'stack'>('update');
// 监听点击数据源方法
const selectDatapoint = (datapoint) => {
    if (datapoint.name == '空货架') {
        updateProductWarehouseForm.name = '';
        updateProductWarehouseForm.number = 0;
        updateProductWarehouseForm._id = datapoint._id;
        updateProductWarehouseForm.ordinate = datapoint.ordinate;
        updateProductWarehouseForm.abscissa = datapoint.abscissa;
        updateProductWarehouseVisible.value = true;
    } else {
        updateProductWarehouseForm.name = datapoint.name.split(' - ')[0].split('：')[1];
        updateProductWarehouseForm.number = Number(datapoint.name.split(' - ')[1].split('：')[1]);
        updateProductWarehouseForm._id = datapoint._id;
        updateProductWarehouseForm.productId = datapoint.productId;
        updateProductWarehouseForm.ordinate = datapoint.ordinate;
        updateProductWarehouseForm.abscissa = datapoint.abscissa;
        updateProductWarehouseVisible.value = true;
    }
};

/* ***********************************初始化仓库布局的dialog属性/方法*********************************** */
// 显示初始化仓库布局的dialog
const initWarehouseVisible = ref(false);
// 横坐标原数据
const originAbscissa = [
    'A',
    'B',
    'C',
    'D',
    'E',
    'F',
    'G',
    'H',
    'I',
    'J',
    'K',
    'L',
    'M',
    'N',
    'O',
    'P',
    'Q',
    'R',
    'S',
    'T',
    'U',
    'V',
    'W',
    'X',
    'Y',
    'Z',
];
// 横坐标
const abscissa = reactive(['A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J']);
// 纵坐标原数据
const originOrdinate = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20];
// 纵坐标
const ordinate = reactive([10, 9, 8, 7, 6, 5, 4, 3, 2, 1]);

// 初始化仓库布局表单
const initWarehouseForm = reactive({
    abscissa: 10,
    ordinate: 10,
});
// 横坐标变化时，重新布局纵坐标
const handleAbscissaChange = (val) => {
    // 清空数据
    abscissa.length = 0;
    // 重置横坐标
    for (let index = 0; index < val; index++) {
        const abs = originAbscissa[index];
        abscissa.push(abs);
    }
};
// 纵坐标变化时，重新布局横坐标
const handleOrdinateChange = (val) => {
    // 清空数据
    ordinate.length = 0;
    const tmp = originOrdinate.slice(0, val).reverse();
    // 重置纵坐标
    for (let index = 0; index < val; index++) {
        const ord = tmp[index];
        ordinate.push(ord);
    }
};
// 初始化仓库布局请求事件
const initWarehouseEvent = () => {
    const warehouseData: { location: string; abscissa: string; ordinate: number }[] = [];
    // 反向循环纵坐标
    const _ordinate = ordinate.reverse();
    // 生成仓库数据
    for (let index = 0; index < abscissa.length; index++) {
        const abs = abscissa[index];
        for (let index = 0; index < ordinate.length; index++) {
            const ord = _ordinate[index];
            warehouseData.push({ location: warehouseName.value, abscissa: abs, ordinate: ord });
        }
    }
    // 初始化仓库
    initWarehouseList(warehouseData).then(() => {
        ElMessage.success('初始化成功');
        initWarehouseVisible.value = false;
        location.reload();
    });
};

/* ***********************************修改仓库数据的dialog属性/方法*********************************** */
// 显示修改仓库数据库的dialog
const updateProductWarehouseVisible = ref(false);
// 修改产品仓库信息的表单
const updateProductWarehouseFormRef = ref<FormInstance>();
// 修改产品仓库信息的表单数据
const updateProductWarehouseForm = reactive({
    // 此id为info中的id
    _id: '',
    name: '',
    number: 0,
    ordinate: 0,
    abscissa: '',
    productId: '',
});
// 表单校验
const rules = reactive<FormRules<typeof updateProductWarehouseForm>>({
    name: [{ required: true, message: '请输入产品名称', trigger: 'change' }],
    number: [{ required: true, message: '请输入产品数量', trigger: 'blur' }],
    ordinate: [{ required: true, message: '请输入仓库位置', trigger: 'blur' }],
    abscissa: [{ required: true, message: '请输入仓库区域', trigger: 'blur' }],
});

// 自动填充框
const queryProductSearch = (queryString: string, cb: any) => {
    const results = queryString ? productList.filter(createFilter(queryString)) : productList;
    // call callback function to return suggestions
    cb(results);
};
// 过滤器
const createFilter = (queryString: string) => {
    return (product: AjaxResponse['productList'][0]) => {
        // 正则处理特殊符号
        const regex = /[.*+?^${}()|[\]\\]/;
        const match = queryString.replace(regex, '\\$&');
        const reg = new RegExp(match, 'i');
        if (reg.test(product.productName)) {
            return true;
        }
    };
};
// 监听选择产品
const handleSelect = (item: Record<string, any>) => {
    let findFlag = false;
    // 检测当前仓库是否有选中的产品
    for (let index = 0; index < dataset.length; index++) {
        // 获取当前仓库纵坐标信息
        const row = dataset[index];

        for (let index = 0; index < row.plots.length; index++) {
            // 获取当前仓库横坐标信息
            const col = row.plots[index];

            if (col.name.includes(item.productName)) {
                // 找到当前仓库有选中的产品
                findFlag = true;
                // 提示用户当前仓库有选中的产品
                ElMessageBox.confirm(`当前仓库有选中的产品，坐标：${col.abscissa} - ${col.ordinate}`, '警告', {
                    confirmButtonText: '继续',
                    cancelButtonText: '退出',
                    type: 'warning',
                })
                    .then(() => {
                        updateProductWarehouseForm.name = item.productName;
                        updateProductWarehouseForm.productId = item._id;
                    })
                    .catch(() => {
                        updateProductWarehouseVisible.value = false;
                    });
            }
        }
    }

    // 当前仓库没有选中产品，直接前往添加
    if (!findFlag) {
        updateProductWarehouseForm.name = item.productName;
        updateProductWarehouseForm.productId = item._id;
    }
};
// 修改产品仓库信息提交事件
const updateProductWarehouseSubmitEvent = async (formEl: FormInstance | undefined) => {
    if (!formEl) return;
    await formEl.validate((valid, fields) => {
        if (valid) {
            updateWarehouseInfo(updateMode.value, updateProductWarehouseForm).then((res) => {
                ElMessage.success(res.message);
                getAllWarehouseListEvent();
                updateProductWarehouseVisible.value = false;
            });
        } else {
            console.log('error submit!', fields);
        }
    });
};
// 删除产品仓库信息提交事件
const deleteProductWarehouseSubmitEvent = async () => {
    ElMessageBox.confirm('是否确认清空当前选中的货架，不会影响堆叠的产品？', '警告', {
        confirmButtonText: '确认',
        cancelButtonText: '取消',
        type: 'warning',
    })
        .then(() => {
            updateWarehouseInfo('delete', updateProductWarehouseForm).then((res) => {
                ElMessage.success(res.message);
                getAllWarehouseListEvent();
                updateProductWarehouseVisible.value = false;
            });
        })
        .catch(() => {
            ElMessage({
                type: 'info',
                message: '取消操作',
            });
        });
};

// 系统配置
const useSystem = useSystemStore();
// 计算宽度
const warehouseListWidth = computed(() => {
    return useSystem.config.isCollapse ? 'calc(100vw - 84px)' : 'calc(100vw - 220px)';
});
</script>

<style scoped lang="scss">
#warehouse-list-container {
    width: v-bind(warehouseListWidth);
    height: calc(100vh - 80px);
}

.my-header {
    display: flex;
    flex-direction: row;
    justify-content: space-around;
    align-items: center;
    gap: 16px;
}

table {
    border-collapse: collapse;
    border: 2px solid rgb(56, 56, 56);
    font-family: sans-serif;
    letter-spacing: 1px;
    text-align: center;
}

th,
td {
    border: 1px solid rgb(63, 63, 63);
    padding: 8px 10px;
    word-break: break-all;
    overflow-wrap: break-word;
}
</style>
